package com.rongxun.http;

import android.content.Context;
import android.support.v4.util.ArrayMap;

import com.rongxun.utils.FlyLog;

import java.lang.reflect.Field;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by nelon on 17-8-16.
 */
public class Api {
    public static final String TAG = "HBC";
    private static final long TIMEOUT = 15;
    private static OkHttpClient okHttpClient;
    private static Map<String, ApiProvider> sProviderMap = new ArrayMap<>();
    public static HttpLoggingInterceptor sloggingInterceptor;

    static {
        sloggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                FlyLog.i(message);
            }
        });
        sloggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                FlyLog.i(message);
            }
        });

        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new TokenInterceptor()) //未所有的网络请求添加token
                .addInterceptor(sloggingInterceptor)
                .connectTimeout(TIMEOUT, TimeUnit.SECONDS)
                .build();
        SSLContext sc = null;

        try {
            sc = SSLContext.getInstance("SSL");
            try {
                sc.init(null, new TrustManager[]{new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                }}, new SecureRandom());
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        HostnameVerifier hv1 = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        String workerClassName = "okhttp3.OkHttpClient";
        try {
            Class workerClass = Class.forName(workerClassName);
            Field hostnameVerifier = workerClass.getDeclaredField("hostnameVerifier");
            hostnameVerifier.setAccessible(true);
            hostnameVerifier.set(okHttpClient, hv1);

            Field sslSocketFactory = workerClass.getDeclaredField("sslSocketFactory");
            sslSocketFactory.setAccessible(true);
            sslSocketFactory.set(okHttpClient, sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static ApiService getAPI(Context context, String pBaseUrl) {
        return createApi(ApiService.class, pBaseUrl);
    }

    /**
     * 根据传入的baseUrl，和api创建retrofit
     *
     * @param clazz
     * @param baseUrl
     * @param <T>
     * @return
     */
    private static <T> T createApi(Class<T> clazz, String baseUrl) {
        //        if (BuildConfig.DEBUG) {
        //            baseUrl = VodServiceBaseUrl;
        //        }
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        return retrofit.create(clazz);
    }

    public static ApiProvider with(String pBaseUrl) {
        ApiProvider apiProvider = sProviderMap.get(pBaseUrl);
        if (apiProvider == null) {
            synchronized (Api.class) {
                apiProvider = sProviderMap.get(pBaseUrl);
                if (apiProvider == null) {
                    apiProvider = new ApiProvider(pBaseUrl, okHttpClient);
                    sProviderMap.put(pBaseUrl, apiProvider);
                }
            }
        }
        return apiProvider;
    }
}

